package Principal;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import entidades.Aeropuerto;
import entidades.Estado;
import entidades.FlightController;
import entidades.IFlightController;
import entidades.Reserva;
import entidades.Vuelo;
import excepciones.VuelosException;

public class Main {

	private static IFlightController grafo;
	private static View view;
	private static DummyGenerator dummy;
	private static Date actualTime;

	public static void main(String[] args) {
		try {
			init();

			int operation = view.getSelectedOperation();
			while (operation != Const.EXIT) {
				try {
					switch (operation) {
					/*
					 * This are the airport methods
					 */
					case Const.AIRPORT_ADD:
						grafo.addAirport(getAirport());
						break;
					case Const.AIRPORT_LIST:
						view.showAirportList(grafo.getAirports());
						break;
					case Const.AIRPORT_DELETE:
						Aeropuerto selectedAirport = getSelectedAirport(grafo.getAirports());
						grafo.deleteAirport(selectedAirport);
						view.deleteAirport(selectedAirport);
						break;
					case Const.AIRPORT_DUMMY_ADD:
						grafo.addAirport(dummy.getDummyAirport());
						break;
					/*
					 * This are the flight methods
					 */
					case Const.FLIGHT_ADD:
						grafo.addFlight(getFlight(grafo.getAirports()));
						break;
					case Const.FLIGHT_LIST:
						view.showFlightList(grafo.getFlights());
						break;
					case Const.FLIGHT_DELETE:
						grafo.deleteFlight(getSelectedFlight(grafo.getFlights()));
						break;
					case Const.FLIGHT_NOTIFY_STATUS:
						break;
					case Const.FLIGHT_CHECK_STATUS:
						grafo.checkFlight(getSelectedFlight(grafo.getFlights()), actualTime);
						break;
					case Const.FLIGHT_SET_STATUS:
						Vuelo flight = view.getSelectedFlight(grafo.getFlights());
						Estado status = view.getSelectedStatus();
						if(flight.validateCambio(flight.getEstado(), status)){
							grafo.setflightSeatus(flight, status);
							view.showAirportStatus(flight.getOrigen(), grafo.getFlights(), flight.getSalida());
							view.showAirportStatus(flight.getDestino(), grafo.getFlights(), flight.getLlegada());	
						}else{
							throw new VuelosException("El vuelo no se puede cambiar al estado solicitado");
						}
						
						break;
					case Const.FLIGHT_DUMMY_ADD:
						grafo.addFlight(dummy.getDummyFlight(grafo.getAirports(), actualTime));
						break;
					/*
					 * This are the reservations methods
					 */
					case Const.RESERVATIONS_ADD:
						grafo.reservar(getSelectedReservation());
						break;
					case Const.RESERVATIONS_LIST:
						view.showReservationList(grafo.getReservations());
						break;
					case Const.RESERVATIONS_CANCEL:
						grafo.cancelReservation(view.getSelectedReservation(grafo.getReservations()));
						break;
					}
				} catch (VuelosException e) {
					view.showErrorMessage(e.getMessage());
				} catch (Exception e) {
					view.showErrorMessage(e.getMessage());
				} finally {
					operation = view.getSelectedOperation();
				}

			}
		} catch (Exception e) {
			System.out.println(Const.MSG_ERROR);
		}
	}

	private static Aeropuerto getSelectedAirport(List<Aeropuerto> airports) {
		return view.getSelectedAirport(airports);
	}

	private static Vuelo getSelectedFlight(List<Vuelo> flights) {
		return view.getSelectedFlight(flights);
	}

	private static Reserva getSelectedReservation() {
		return view.getNewReservation(grafo);
	}

	private static void init() {
		grafo = new FlightController();
		view = new ConsoleView();
		dummy = new DummyGenerator();
		actualTime = new Date();

		/*
		 * 
		 */
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");

			Aeropuerto a = new Aeropuerto();
			a.setName("A");
			grafo.addAirport(a);

			Aeropuerto b = new Aeropuerto();
			b.setName("B");
			grafo.addAirport(b);

			Aeropuerto c = new Aeropuerto();
			c.setName("C");
			grafo.addAirport(c);

			Aeropuerto d = new Aeropuerto();
			d.setName("D");
			grafo.addAirport(d);

			Aeropuerto e = new Aeropuerto();
			e.setName("E");
			grafo.addAirport(e);

			Aeropuerto f = new Aeropuerto();
			f.setName("F");
			grafo.addAirport(f);

			Aeropuerto g = new Aeropuerto();
			g.setName("G");
			grafo.addAirport(g);

			Vuelo v = new Vuelo();
			v.setNroVuelo("V1");
			v.setOrigen(a);
			v.setDestino(b);
			v.setSalida(sdf.parse("28/11/2012 15:30"));
			v.setLlegada(sdf.parse("28/11/2012 18:00"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V2");
			v.setOrigen(b);
			v.setDestino(e);
			v.setSalida(sdf.parse("28/11/2012 19:45"));
			v.setLlegada(sdf.parse("28/11/2012 22:00"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V3");
			v.setOrigen(a);
			v.setDestino(c);
			v.setSalida(sdf.parse("28/11/2012 23:15"));
			v.setLlegada(sdf.parse("29/11/2012 04:00"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V4");
			v.setOrigen(c);
			v.setDestino(e);
			v.setSalida(sdf.parse("29/11/2012 04:30"));
			v.setLlegada(sdf.parse("29/11/2012 05:00"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V5");
			v.setOrigen(f);
			v.setDestino(a);
			v.setSalida(sdf.parse("29/11/2012 06:30"));
			v.setLlegada(sdf.parse("29/11/2012 07:30"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V6");
			v.setOrigen(d);
			v.setDestino(f);
			v.setSalida(sdf.parse("29/11/2012 08:00"));
			v.setLlegada(sdf.parse("29/11/2012 10:30"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V7");
			v.setOrigen(c);
			v.setDestino(d);
			v.setSalida(sdf.parse("29/11/2012 11:45"));
			v.setLlegada(sdf.parse("29/11/2012 15:30"));
			v.setCantDisponible(10);
			v.setPrecio(10020.60);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V8");
			v.setOrigen(e);
			v.setDestino(d);
			v.setSalida(sdf.parse("29/11/2012 16:30"));
			v.setLlegada(sdf.parse("29/11/2012 17:30"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V9");
			v.setOrigen(d);
			v.setDestino(g);
			v.setSalida(sdf.parse("29/11/2012 19:00"));
			v.setLlegada(sdf.parse("29/11/2012 20:40"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

			v = new Vuelo();
			v.setNroVuelo("V10");
			v.setOrigen(e);
			v.setDestino(g);
			v.setSalida(sdf.parse("29/11/2012 21:30"));
			v.setLlegada(sdf.parse("29/11/2012 23:30"));
			v.setCantDisponible(10);
			v.setPrecio(530.25);
			grafo.addFlight(v);

		} catch (Exception e) {
			view.showErrorMessage(e.getMessage());
		}
	}

	protected static Aeropuerto getAirport() {
		Aeropuerto airport = new Aeropuerto();
		view.getAirport(airport);
		return airport;
	}

	protected static Vuelo getFlight(List<Aeropuerto> airports) {
		Vuelo flight = new Vuelo();
		return view.getFlight(flight, airports);
	}

	// try {
	// Main.iniciar();
	//
	// System.out.println(Main.grafo.toString());
	//
	// List<List<Vuelo>> caminos =
	// grafo.obtenerCaminos(grafo.getAeropuertos().get(0),
	// grafo.getAeropuertos().get(5), null, 0, 0, null);
	//
	// for (List<Vuelo> camino : caminos) {
	// String out = "";
	// for (Vuelo vuelo : camino) {
	// out += " - " + vuelo.getNroVuelo();
	// }
	// System.out.println(out);
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	//
	//
	// private static void iniciar() throws VuelosException {
	//
	// Main.grafo = new Grafo();
	//
	// Aeropuerto a = new Aeropuerto();
	// a.setName("A");
	// Main.grafo.agregarAeropuerto(a);
	//
	// Aeropuerto b = new Aeropuerto();
	// b.setName("B");
	// Main.grafo.agregarAeropuerto(b);
	//
	// Aeropuerto c = new Aeropuerto();
	// c.setName("C");
	// Main.grafo.agregarAeropuerto(c);
	//
	// Aeropuerto d = new Aeropuerto();
	// d.setName("D");
	// Main.grafo.agregarAeropuerto(d);
	//
	// Aeropuerto e = new Aeropuerto();
	// e.setName("E");
	// Main.grafo.agregarAeropuerto(e);
	//
	// Aeropuerto f = new Aeropuerto();
	// f.setName("F");
	// Main.grafo.agregarAeropuerto(f);
	//
	// Aeropuerto g = new Aeropuerto();
	// g.setName("G");
	// Main.grafo.agregarAeropuerto(g);
	//
	// Vuelo v = new Vuelo();
	// v.setNroVuelo("V1");
	// v.setOrigen(a);
	// v.setDestino(b);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V2");
	// v.setOrigen(b);
	// v.setDestino(e);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V3");
	// v.setOrigen(a);
	// v.setDestino(c);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V4");
	// v.setOrigen(c);
	// v.setDestino(e);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V5");
	// v.setOrigen(f);
	// v.setDestino(a);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V6");
	// v.setOrigen(d);
	// v.setDestino(f);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V7");
	// v.setOrigen(c);
	// v.setDestino(d);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V8");
	// v.setOrigen(e);
	// v.setDestino(d);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V9");
	// v.setOrigen(d);
	// v.setDestino(g);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V10");
	// v.setOrigen(e);
	// v.setDestino(g);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V11");
	// v.setOrigen(d);
	// v.setDestino(a);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V12");
	// v.setOrigen(e);
	// v.setDestino(c);
	// Main.grafo.agregarVuelo(v);
	//
	// v = new Vuelo();
	// v.setNroVuelo("V13");
	// v.setOrigen(g);
	// v.setDestino(b);
	// Main.grafo.agregarVuelo(v);
	//
	// }

}
